<?php
class Cart_WebpayController extends Ext_Controller_Action
{
	private $_log;
	public function preDispatch()
	{
		parent::preDispatch();
		$writer = new Zend_Log_Writer_Stream( 
			Zend_Registry::get('config')->webpay->log->transaction
		);
		$this->_log = new Zend_Log( $writer );
		$this->_log->info( "Webpay Method Selected" );
	}

	
	public function indexAction()
	{
		try{
			$client = new Zend_XmlRpc_Client( 
				Zend_Registry::get('config')->api->cart->url 
			);

            $userId = (int)$this->_getParam('userId');
			$credential = $this->_getParam('credential');
            $amount = $this->_getParam('amount');
			$orderId = (int)$this->_getParam('orderId');
            $urlSuccess = $this->_getParam('urlSuccess');
            $urlFail = $this->_getParam('urlFail');
            $sourceObjectName = $this->_getParam('sourceObjectName');
			$paymentMethodId = $this->_config->Payment->webpay->id;
            $user = new Ext_Model_User();
            if( !$user->checkCredential( $userId, $credential )){
                $this->_log->info("Credential is broken");
                throw new Ext_Exception ( 'Credential is broken');
            }

            $internalWebpaySession = array();
			$internalWebpaySession['amount'] = round( (round($amount) * 100) );
            $internalWebpaySession['orderId'] = $orderId;
            $internalWebpaySession['userId'] = $userId;
            $internalWebpaySession['urlSuccess'] = $urlSuccess;
            $internalWebpaySession['urlFail'] = $urlFail;
            $internalWebpaySession['credential'] = $credential;
            $internalWebpaySession['sourceObjectName'] = $sourceObjectName;


			$accountModel = new Cart_Model_Account();
            $validAccount = false;
            try{
                $accountId = $accountModel->getAccountId( $internalWebpaySession['userId'], $internalWebpaySession['credential'],
                                                          $internalWebpaySession['userId'], $internalWebpaySession['sourceObjectName'] );
                $validAccount = true;
            } catch( Exception $error ) {
                $validAccount = false;
				$this->_log->info("No se pudo verificar la cuenta del usuario");
				$this->_redirect( $internalWebpaySession['urlFail'] );
				exit(0);
            }

            if ( $validAccount == true )
			{
				$webPayModel = new Cart_Model_WebPay();
				$transactionModel = new Cart_Model_Transaction();
				try{
					$getTrans = $webPayModel->getTransaction( $internalWebpaySession['orderId'] );
				}catch( Exception $error ) {
					$this->_log->info("No se pudo verificar si la transaccion estaba cursada");
                    $this->_redirect( $internalWebpaySession['urlFail'] );
                    exit(0);
				}

				if ( count( $getTrans ) > 0 )
				{
					$this->_log->info("Esta transaccion ya estaba abierta");
					if ( $getTrans[0]['codigo_autorizacion'] != null )
	                {
						$this->_log->info("Esta transaccion ya fue cursada por Webpay");
						$this->_redirect( $internalWebpaySession['urlFail'] );
		                exit(0);
					}
				}

				$data = array(
                            'TBK_ORDEN_COMPRA' => $internalWebpaySession['orderId'],
                            'USER_ID' => $internalWebpaySession['userId'],
                            'ACCOUNT_ID' => $accountId,
                            'PAYMENT_METHOD_ID' => Zend_Registry::get('config')->Payment->webpay->id,
							'OBJECT' => serialize( $internalWebpaySession ),
							'MODIFICATION_DATE' => Ext_Db_Date::now(),
							'AMOUNT' => $internalWebpaySession['amount'],
							'STATUS' => 'A'
                		);

				try{
					$saveTrans = $transactionModel->saveTransaction( $data );
				}catch( Exception $error ) {
					$this->_log->info("No se pudo grabar el encabezado de la transaccion");
                    $this->_redirect( $internalWebpaySession['urlFail'] );
                    exit(0);
				}

	            // Save Webpay Transaction
				$idSession = Zend_Session::getId();
				$data = array(
				            'TBK_ORDEN_COMPRA' => $internalWebpaySession['orderId'],
				            'TBK_TIPO_TRANSACCION' =>  null,
				            'TBK_MONTO' => $internalWebpaySession['amount'],
				            'TBK_CODIGO_AUTORIZACION' => null,
				            'TBK_FINAL_NUMERO_TARJETA' => null,
				            'TBK_TIPO_PAGO' => null,
				            'TBK_NUMERO_CUOTAS' => null,
				            'TBK_RESPUESTA' => null,
				            'TBK_FECHA_CONTABLE' => null,
				            'TBK_FECHA_TRANSACCION' => null,
				            'TBK_HORA_TRANSACCION' => null,
				            'TBK_ID_SESION' => $idSession,
				            'TBK_ID_TRANSACCION' => null,
				            'TBK_TASA_INTERES_MAX' => null,
				            'TBK_MAC' => null
					    );

				try{
	    	        $saveWebpayTrans = $webPayModel->saveTransaction( $data );
				}catch( Exception $error ) {
					$this->_log->info("No se pudo grabar el registro de Webpay");
                    $this->_redirect( $internalWebpaySession['urlFail'] );
                    exit(0);
				}

				if( !$this->getRequest() ) {
	   	            $this->_log->info("Error in Webpay Initilization. Exit");
					throw new Ext_Exception( 'Error in Webpay Initilization. Exit' );
				}
		
				$this->_log->info("Se envia transaccion $orderId con monto ".round( (round( $amount ) * 100) ));	
				$dataToWP = array(
					'TBK_MONTO' => round( (round( $amount ) * 100) ),
					'TBK_ORDEN_COMPRA' => $orderId,
					'TBK_ID_SESION' => $idSession,
					'TBK_URL_EXITO' => $this->_config->webpay->base->result->url.'/Cart/webpay/finished/orderId/'. $orderId ,
					'TBK_URL_FRACASO' => $this->_config->webpay->base->result->url.'/Cart/webpay/failed/'
				);

				$this->view->webpayForm = new Cart_Form_WebPay();
				$this->view->webpayForm->populate( $dataToWP );
				$this->view->webpayForm->setAction( 
					Zend_Registry::get('config')->webpay->cgi->pago 
				);
			}

		}catch( Exception $e ) {
	        $this->_log->info("Exception");
			throw new Ext_Exception( $e );
		}	
	}
	
	public function closeorderAction()
	{
		$this->_log->info("LLega retorno de Webpay");

        if ( $this->_hasParam('TBK_ID_TRANSACCION'))  {   
            $tbkIdTransac = $this->_getParam('TBK_ID_TRANSACCION');
        }   

        $request = $this->_getAllParams();

		$this->_log->info("Building file for mac verification...");


		$filename = "webpaygw/log/log_$tbkIdTransac.txt";
        $fp = fopen($filename, "w");
        foreach( $request as $key => $val )
        {
	        if ( $key != 'controller' && $key != 'action' && $key != 'module' )
	        {
                fwrite($fp,"$key=$val&");
	        }
        }
        fclose($fp);


        $this->_log->info("Verifying mac...");
        $cmdline = Zend_Registry::get('config')->webpay->cgi->mac . " $filename";

        exec($cmdline, $result, $retint);

        $tbkResponse = $this->_getParam('TBK_RESPUESTA');
       	$this->_log->info("result[0] = " . $result[0]);
        $this->_log->info("tbk_response" . $tbkResponse);

        // Verificar si la transaccion esta duplicada
        $webPayModel = new Cart_Model_WebPay();
        $getTransaction = $webPayModel->getTransaction( $this->_getParam('TBK_ORDEN_COMPRA') );

		$transactionModel = new Cart_Model_Transaction();
        $internalTransaction = $transactionModel->getTransaction( $this->_getParam('TBK_ORDEN_COMPRA') );
		$internalWebpaySession = unserialize( $internalTransaction[0]['object'] );

        if ( $getTransaction[0]['codigo_autorizacion'] != null ) {
            $this->_log->info( "Duplicate Transaction" );
        }

        if ( $tbkResponse == 0 && isset($result[0]) && $result[0] == "CORRECTO" && $getTransaction[0]['codigo_autorizacion'] == null )
		{

	        $this->_log->info("verificando respuesta...");

            if ( $this->_getParam('TBK_ORDEN_COMPRA') == $internalWebpaySession['orderId']  
                               && $this->_getParam('TBK_MONTO') == $internalWebpaySession['amount'] ) {

                $accountId = $internalTransaction[0]['account_id'];
                if ( $accountId > 0 )
                {
                    try{
                        $sourceObjectId = 'PG_WEBPAY';
                        $sourceObjectCode = $this->_getParam('TBK_ORDEN_COMPRA');   
						
						$this->_log->info( 'Aceptando Orden de Compra :'.$this->_getParam('TBK_ORDEN_COMPRA') );

                        // Save Webpay Transaction
                        $webPayModel = new Cart_Model_WebPay();
                        $saveWebpayTrans = $webPayModel->saveTransaction( $request );

						$this->_log->info( 'Orden de Compra :'.$this->_getParam('TBK_ORDEN_COMPRA').' grabada correctamente' );

		                $data = array(
                            'TBK_ORDEN_COMPRA' => $internalTransaction[0]['id_transaction'],
                            'USER_ID' => $internalTransaction[0]['user_id'],
                            'ACCOUNT_ID' => $internalTransaction[0]['account_id'],
                            'PAYMENT_METHOD_ID' => $internalTransaction[0]['payment_method_id'],
                            'OBJECT' => $internalTransaction[0]['object'],
                            'MODIFICATION_DATE' => $internalTransaction[0]['modification_date'],
                            'AMOUNT' => $internalTransaction[0]['amount'],
                            'STATUS' => 'P'
                        );
						$transactionModel->saveTransaction( $data );

						
                        // Insert Account Transaction
						$accountModel = new Cart_Model_Account();
						$amountToCharge = round( $this->_getParam('TBK_MONTO') / 100 );
                        $accountModel->insertTransaction( $internalWebpaySession['userId'], $internalWebpaySession['credential'],
														  $accountId, $amountToCharge, $sourceObjectCode, $sourceObjectId );

                        $this->_log->info("Transaccion Aceptada [".$this->_getParam('TBK_ORDEN_COMPRA')."]");
                        $this->_log->info("TRX: ACEPTADA.");
                        $this->view->status = "ACEPTADO";
                    } catch( Exception $error ) {
                        $this->_log->info("Se produjo algun error en grabacion de la transaccion");
                        $this->view->status = "RECHAZADO";
                        $this->_log->info("TRX: RECHAZADA.");
                    }
                } else {
                    $this->_log->info("No se encontro la cuenta corriente del usuario");
                    $this->view->status = "RECHAZADO";
                    $this->_log->info("TRX: RECHAZADA.");
                }

            } else {
                $this->_log->info("No coinciden los datos con monto ".$this->_getParam('TBK_MONTO')." y ".$this->_getParam('TBK_ORDEN_COMPRA')." VS ".$internalWebpaySession['orderId']." y ".$internalWebpaySession['amount'] );
                $this->view->status = "RECHAZADO";
                $this->_log->info("TRX: RECHAZADA.");
            }

        } else {

            if ( $tbkResponse == -1 || !isset($result[0]) || $result[0] != "CORRECTO" )
            {
                $this->_log->info("Error in mac verification or tbk_response = -1");
                $this->view->status = "ACEPTADO";
                $this->_log->info("TRX: ACEPTADA.");
            } else {
                $this->_log->info("La transaccion existe [ ".$this->_getParam('TBK_ORDEN_COMPRA')." ] y ya fue cursada por WEBPAY");
                $this->view->status = "RECHAZADO";
                $this->_log->info("TRX: RECHAZADA.");
            }

        }
        $this->_log->info("listo webpay");
	}
	
	public function finishedAction()
	{
		$transactionModel = new Cart_Model_Transaction();
        $internalTransaction = $transactionModel->getTransaction( $this->_getParam('TBK_ORDEN_COMPRA') );
        $internalWebpaySession = unserialize( $internalTransaction[0]['object'] );
	
        $webPayModel = new Cart_Model_WebPay();
        $getTransaction = $webPayModel->getTransaction( $this->_getParam('orderId') );
        $urlSuccess = $internalWebpaySession['urlSuccess'];
        $urlFail = $internalWebpaySession['urlFail'];

        // Verifico que exista el Registro en la base webpay con ese order_id
        if (isset($getTransaction[0]['codigo_autorizacion']) && $getTransaction[0]['codigo_autorizacion'] != null) {   
            $this->_log->info("Successful ".$this->_getParam('orderId'));
            $this->_log->info("Finish Webpay Transaction Successful");
            $this->_redirect( $urlSuccess );
        } else {
            $this->_log->info("Fail get transaction ".$this->_getParam('orderId'));
            $this->_log->info("Finish Webpay Transaction Error");
            $this->_redirect( $urlFail );
        }
	}

	public function failedAction()
	{
		$transactionModel = new Cart_Model_Transaction();
		$internalTransaction = $transactionModel->getTransaction( $this->_getParam('TBK_ORDEN_COMPRA') );
		$internalWebpaySession = unserialize( $internalTransaction[0]['object'] );

        $urlFail = $internalWebpaySession['urlFail'];
        $this->_log->info("Finish Webpay Transaction Error");

        $this->_redirect( $urlFail );
	}

}
